package com.github.wxiaoqi.security.crm.core.biz;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.util.StringUtil;
import com.github.wxiaoqi.security.auth.common.util.SnowFlake;
import com.github.wxiaoqi.security.common.crm.request.IntoAccountRequest;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.util.EntityUtils;
import com.github.wxiaoqi.security.common.util.MD5;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccount;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccount;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.PersonalBilling;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalBillingMapper;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

/**
 * 入账相关的操作
 */
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
public class CommonIntoAccountBiz {

	@Value("${bountyHunter.balanceSaltValue}")
	private String balanceSaltValue;
	@Autowired
	private MerchantAccountMapper merAccountMapper;
	@Autowired
	private MerchantAccountJournalMapper accountJournalMapper;
	@Autowired
	private PersonalBillingMapper personalBillingMapper;
	@Autowired
	private PersonalAccountMapper personalAccountMapper;
	@Autowired
	private PersonalAccountJournalMapper personalAccountJournalMapper;
	/**
	 * 第三方支付成功后回调后的操作: 1、商户账号入账 2、新增商户账户流水记录 3、新增个人账单记录
	 */
	public Map<String, Object> intoAccount(IntoAccountRequest intoAccountRequest) {
		log.info("入账（第三方支付）请求参数：{}" + EntityUtils.beanToMap(intoAccountRequest));
		Map<String, Object> response = new HashMap<String, Object>();
		MerchantAccount queryAccount = new MerchantAccount();
		queryAccount.setMerchantId(intoAccountRequest.getMerchantId());
		queryAccount.setCustomerType(intoAccountRequest.getCustomerType());
		queryAccount.setAccountType(intoAccountRequest.getAccountType());
		MerchantAccount merchantAccount = merAccountMapper.selectOne(queryAccount);
		String accountId = "";
		if (null == merchantAccount) {// 商户账号还未开户
			/**
			 * 商户账号开通
			 */
			try {
				MerchantAccount newAccount = new MerchantAccount();
				accountId = String.valueOf(SnowFlake.getId());
				newAccount.setAccountId(accountId);
				newAccount.setPlatformId(intoAccountRequest.getPlatformId());
				newAccount.setMerchantId(intoAccountRequest.getMerchantId());
				newAccount.setCustomerType(intoAccountRequest.getCustomerType());
				newAccount.setAccountType(intoAccountRequest.getAccountType());
				newAccount.setCcy("CNY");
				newAccount.setFreezeBalance(BigDecimal.ZERO);
				//newAccount.setAccountBalance(BigDecimal.ZERO);
				//newAccount.setCheckSum(MD5.sign(newAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));// 商户账户余额加密后的值
				newAccount.setAccountBalance(new BigDecimal(intoAccountRequest.getTradeAmt()));
				newAccount.setCheckSum(MD5.sign(intoAccountRequest.getTradeAmt().toString(), balanceSaltValue, "utf-8"));
				newAccount.setStatus("00");//账户状态 00：正常，01：冻结
				newAccount.setCreateTime(new Date());
				merAccountMapper.insertSelective(newAccount);
			} catch (Exception e) {
				e.printStackTrace();
				log.info("入账（第三方支付）报错。。。。。。{}", e.getMessage());
				response.put("code", ResponseCode.MER_ACC_OPENFAIL.getCode());
				response.put("msg", ResponseCode.MER_ACC_OPENFAIL.getMessage());
				return response;
			}
		} else if (null != merchantAccount && "01".equals(merchantAccount.getStatus())) {// 商户账号已被冻结
			response.put("code", ResponseCode.MER_ACC_FREEZE.getCode());
			response.put("msg", ResponseCode.MER_ACC_FREEZE.getMessage());
			log.info("入账（第三方支付）返回参数。。。。。。{}", response);
			return response;
		}
		/**
		 * 修改账户余额
		 */
		try {
			if(null!=merchantAccount){
				if(!MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())){
					response.put("code", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getCode());
					response.put("msg", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getMessage());
					log.info("入账（第三方支付）返回参数。。。。。。{}", response);
					return response;
				}
				merchantAccount.setAccountBalance(merchantAccount.getAccountBalance().add(new BigDecimal(intoAccountRequest.getTradeAmt())));
				merchantAccount.setCheckSum(MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
				merAccountMapper.updateByPrimaryKeySelective(merchantAccount);
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.info("入账（第三方支付）报错。。。。。。{}", e.getMessage());
			response.put("code", ResponseCode.MER_ACC_INTOACCOUNTFAIL.getCode());
			response.put("msg", ResponseCode.MER_ACC_INTOACCOUNTFAIL.getMessage());
			return response;
		}
		/***
		 * 新增商户账户流水 和个人账单记录
		 */
		if (StringUtils.isEmpty(accountId)) {
			accountId = merchantAccount.getAccountId();
		}
		try {
			MerchantAccountJournal accountJournal = new MerchantAccountJournal();
			accountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			accountJournal.setPlatformId(intoAccountRequest.getPlatformId());
			accountJournal.setMerchantId(intoAccountRequest.getMerchantId());
			accountJournal.setAccountId(accountId);
			accountJournal.setAccountType(intoAccountRequest.getAccountType());
			accountJournal.setOrderNo(intoAccountRequest.getOrderNo());
			accountJournal.setInOutFlag("1");//来往标志  1：来账   2：往账
			accountJournal.setTradeAmt(new BigDecimal(intoAccountRequest.getTradeAmt()));
			accountJournal.setTradeType("03");// 交易类型 01：充值，02：提现，03：支付
			accountJournal.setCreateTime(new Date());
			accountJournalMapper.insertSelective(accountJournal);
			PersonalBilling personalBilling = new PersonalBilling();
			personalBilling.setBillId(String.valueOf(SnowFlake.getId()));
			personalBilling.setPlatformId(intoAccountRequest.getPlatformId());
			personalBilling.setPersonalId(intoAccountRequest.getPersonalId());
			personalBilling.setOrderNo(intoAccountRequest.getOrderNo());
			personalBilling.setInOutFlag("2");//来往标志  1：入账   2：出账
			personalBilling.setTradeAmt(new BigDecimal(intoAccountRequest.getTradeAmt()));
			// personalBilling.setSellerId(sellerId);待定
			personalBilling.setSellerType(intoAccountRequest.getCustomerType());
			personalBilling.setProduceInfo(intoAccountRequest.getProduceInfo());
			personalBilling.setPayWay(intoAccountRequest.getPayType());
			personalBilling.setCreateTime(new Date());
			personalBilling.setTradeType("01");//交易类型（支付:01，退款:02，提现:03，充值:04）
			personalBilling.setStatus("00");//账单状态（付款成功 00 ，充值成功 01 ，退款申请成功02，退款成功03， 提现申请成功04 ，提现处理成功 05 ）
			personalBillingMapper.insertSelective(personalBilling);
			response.put("code", ResponseCode.OK.getCode());
			response.put("msg", ResponseCode.OK.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			log.info("入账（第三方支付）报错。。。。。。{}", e.getMessage());
			response.put("code", ResponseCode.MER_ACC_INTOACCOUNTFAIL.getCode());
			response.put("msg", ResponseCode.MER_ACC_INTOACCOUNTFAIL.getMessage());
			return response;
		}
		return response;
	}

	/***
	 * 账户余额支付成功回调后的操作 1、个人账户余额扣除 2、商户账户余额增加 3、新增个人账单记录、个人账户流水记录、商户账户流水记录
	 */
	@SuppressWarnings("unused")
	public Map<String, Object> balancePayintoAccount(IntoAccountRequest intoAccountRequest) {
		log.info("入账（账户余额支付）请求参数：{}" + EntityUtils.beanToMap(intoAccountRequest));
		Map<String, Object> response = new HashMap<String, Object>();
		PersonalAccount queryPersonalAccount = new PersonalAccount();
		queryPersonalAccount.setPlatformId(intoAccountRequest.getPlatformId());
		queryPersonalAccount.setPersonalId(intoAccountRequest.getPersonalId());
		queryPersonalAccount.setAccountType(intoAccountRequest.getAccountType());
		PersonalAccount personalAccount = personalAccountMapper.selectOne(queryPersonalAccount);
		MerchantAccount queryAccount = new MerchantAccount();
		queryAccount.setMerchantId(intoAccountRequest.getMerchantId());
		queryAccount.setCustomerType(intoAccountRequest.getCustomerType());
		queryAccount.setAccountType(intoAccountRequest.getAccountType());
		MerchantAccount merchantAccount = merAccountMapper.selectOne(queryAccount);
		MerchantAccount newAccount = new MerchantAccount();
		String merAccountId = "";
		if (null == merchantAccount) {// 商户账号还未开户
			/**
			 * 商户账号开通
			 */
			try {
				merAccountId = String.valueOf(SnowFlake.getId());
				newAccount.setAccountId(merAccountId);
				newAccount.setPlatformId(intoAccountRequest.getPlatformId());
				newAccount.setMerchantId(intoAccountRequest.getMerchantId());
				newAccount.setCustomerType(intoAccountRequest.getCustomerType());
				newAccount.setAccountType(intoAccountRequest.getAccountType());
				newAccount.setCcy("CNY");
				newAccount.setFreezeBalance(BigDecimal.ZERO);
				//newAccount.setAccountBalance(BigDecimal.ZERO);
				//newAccount.setCheckSum(MD5.sign(newAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));// 商户账户余额加密后的值
				newAccount.setAccountBalance(new BigDecimal(intoAccountRequest.getTradeAmt()));
				newAccount.setCheckSum(MD5.sign(intoAccountRequest.getTradeAmt().toString(), balanceSaltValue, "utf-8"));
				newAccount.setStatus("00");//账户状态 00：正常，01：冻结
				newAccount.setCreateTime(new Date());
				merAccountMapper.insertSelective(newAccount);
			} catch (Exception e) {
				e.printStackTrace();
				log.info("入账（账户余额支付）报错。。。。。。{}", e.getMessage());
				response.put("code", ResponseCode.MER_ACC_OPENFAIL.getCode());
				response.put("msg", ResponseCode.MER_ACC_OPENFAIL.getMessage());
				return response;
			}
		} else if (null != merchantAccount && "01".equals(merchantAccount.getStatus())) {// 商户账号已被冻结
			response.put("code", ResponseCode.MER_ACC_FREEZE.getCode());
			response.put("msg", ResponseCode.MER_ACC_FREEZE.getMessage());
			log.info("入账（账户余额支付）返回参数。。。。。。{}", response);
			return response;
		}
		try {
		/***
		 * 检验余额账户金额是否充足 与  用户账户及商户账户余额加密和数据库中加密后的余额比对
		 * 减除 个人账号余额 和增加商户账户余额
		 * */
		if(personalAccount.getAccountBalance().compareTo(new BigDecimal(intoAccountRequest.getTradeAmt()))<0){//账户余额不足
			response.put("code", ResponseCode.PER_ACC_BALANCE_NOT_ENOUGH.getCode());
			response.put("msg", ResponseCode.PER_ACC_BALANCE_NOT_ENOUGH.getMessage());
			log.info("入账（账户余额支付）返回参数。。。。。。{}", response);
			return response;
		}
		if(!MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())){
			response.put("code", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getCode());
			response.put("msg", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getMessage());
			log.info("入账（账户余额支付）返回参数。。。。。。{}", response);
			return response;
		}
		
		personalAccount.setAccountBalance(personalAccount.getAccountBalance().subtract(new BigDecimal(intoAccountRequest.getTradeAmt())));
		personalAccount.setCheckSum(MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
		personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
		if(null!=merchantAccount){//商户账户已存在则直接修改账户余额
			if(!MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())){
				response.put("code", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getCode());
				response.put("msg", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getMessage());
				log.info("入账（账户余额支付）返回参数。。。。。。{}", response);
				return response;
			}
			merchantAccount.setAccountBalance(merchantAccount.getAccountBalance().add(new BigDecimal(intoAccountRequest.getTradeAmt())));
			merchantAccount.setCheckSum(MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
			merAccountMapper.updateByPrimaryKeySelective(merchantAccount);
		}
		/**
		 * 商户账户流水记录、新增个人账单记录、个人账户流水记录、
		 * */
		if (StringUtils.isEmpty(merAccountId)) {
			merAccountId = merchantAccount.getAccountId();
		}
			MerchantAccountJournal accountJournal = new MerchantAccountJournal();
			accountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			accountJournal.setPlatformId(intoAccountRequest.getPlatformId());
			accountJournal.setMerchantId(intoAccountRequest.getMerchantId());
			accountJournal.setAccountId(merAccountId);
			accountJournal.setAccountType(intoAccountRequest.getAccountType());
			accountJournal.setOrderNo(intoAccountRequest.getOrderNo());
			accountJournal.setInOutFlag("1");//来往标志  1：来账   2：往账
			accountJournal.setTradeAmt(new BigDecimal(intoAccountRequest.getTradeAmt()));
			accountJournal.setTradeType("03");// 交易类型 01：充值，02：提现，03：支付
			accountJournal.setCreateTime(new Date());
			accountJournalMapper.insertSelective(accountJournal);
			PersonalBilling personalBilling = new PersonalBilling();
			personalBilling.setBillId(String.valueOf(SnowFlake.getId()));
			personalBilling.setPlatformId(intoAccountRequest.getPlatformId());
			personalBilling.setPersonalId(intoAccountRequest.getPersonalId());
			personalBilling.setOrderNo(intoAccountRequest.getOrderNo());
			personalBilling.setInOutFlag("2");//来往标志  1：来账   2：往账
			personalBilling.setTradeAmt(new BigDecimal(intoAccountRequest.getTradeAmt()));
			// personalBilling.setSellerId(sellerId);待定
			personalBilling.setSellerType(intoAccountRequest.getCustomerType());
			personalBilling.setProduceInfo(intoAccountRequest.getProduceInfo());
			personalBilling.setPayWay(intoAccountRequest.getPayType());
			personalBilling.setCreateTime(new Date());
			personalBilling.setTradeType("01");//交易类型（支付:01，退款:02，提现:03，充值:04）
			personalBilling.setStatus("00");//账单状态（付款成功 00 ，充值成功 01 ，退款申请成功02，退款成功03， 提现申请成功04 ，提现处理成功 05 ）
			personalBillingMapper.insertSelective(personalBilling);
			PersonalAccountJournal personalAccountJournal=new PersonalAccountJournal();
			personalAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			personalAccountJournal.setPlatformId(intoAccountRequest.getPlatformId());
			personalAccountJournal.setPersonalId(intoAccountRequest.getPersonalId());
			personalAccountJournal.setAccountId(personalAccount.getAccountId());
			personalAccountJournal.setAccountType(personalAccount.getAccountType());
			personalAccountJournal.setOrderNo(intoAccountRequest.getOrderNo());
			personalAccountJournal.setInOutFlag("2");//来往标志  1：来账   2：往账
			personalAccountJournal.setTradeAmt(new BigDecimal(intoAccountRequest.getTradeAmt()));
			personalAccountJournal.setTradeType("02");//交易类型（支付:01，退款:02，提现:03，充值:04）
			personalAccountJournal.setCreateTime(new Date());
			personalAccountJournalMapper.insertSelective(personalAccountJournal);
			response.put("code", ResponseCode.OK.getCode());
			response.put("msg", ResponseCode.OK.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			log.info("入账（账户余额支付）报错。。。。。。{}", e.getMessage());
			response.put("code", ResponseCode.MER_ACC_INTOACCOUNTFAIL.getCode());
			response.put("msg", ResponseCode.MER_ACC_INTOACCOUNTFAIL.getMessage());
			return response;
		}
		return response;
	}

}
